using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AnalysisServices.AdomdServer;

namespace ISV_1.ASClientExtensions
{
    struct MDXCommands
    {
        public String databaseName;
        public String cubeName;
        public String mdxCommand;

        public MDXCommands(String db, String cube, String cmd)
        {
            databaseName = db;
            cubeName = cube;
            mdxCommand = cmd;
        }
    }
    class AuthoringAndManagement
    {
        //Users are defined as Name and PermissionsMap
        static Dictionary<String, UInt32> users = new Dictionary<string, uint>();

        //MDX objects are defined as Permissionsmap and MDX script
        //Note: no description is given on how to assemble multiple MDX scripts for the same permission map
        static Dictionary<UInt32, MDXCommands> members = new Dictionary<UInt32, MDXCommands>();
        static Dictionary<UInt32, MDXCommands> sets = new Dictionary<UInt32, MDXCommands>();
        static Dictionary<UInt32, MDXCommands> kpis = new Dictionary<UInt32, MDXCommands>();

        public AuthoringAndManagement()
        {
            LoadAll();
        }

        ~AuthoringAndManagement()
        {
        }

        public static void LoadAll()
        {
            //Go to authoring database and retrieve users info
            users.Add("user1".ToLowerInvariant(), 0x1111);
            users.Add("user2".ToLowerInvariant(), 0x0030);
            users.Add("user3".ToLowerInvariant(), 0x008F);

            //Go to the authoring database and retrieve: MDX members commands, MDX sets commands, and MDX kpis commands
            //Adding retrieved members to 'members' dictionary
            members.Add(0xFFFF, new MDXCommands("Adventure Works DW", "Adventure Works", "alter cube [Adventure Works]create member [Measures].[Gross Internet Profit] as [Measures].[Internet Sales Amount] - [Measures].[Internet Total Product Cost], CAPTION='Gross Internet Profit', DISPLAY_FOLDER='ISV_1/Common', ASSOCIATED_MEASURE_GROUP='Internet Sales'"));
            members.Add(0x3000, new MDXCommands("Adventure Works DW", "Adventure Works", "alter cube [Adventure Works]create member [Measures].[Average Item Freight Cost] as [Measures].[Reseller Freight Cost]/[Measures].[Reseller Order Quantity], CAPTION='Average Item Freight Cost', DISPLAY_FOLDER='ISV_1/Operations', ASSOCIATED_MEASURE_GROUP='Reseller Sales'"));
            members.Add(0x0060, new MDXCommands("Adventure Works DW", "Adventure Works", "alter cube [Adventure Works]create member [Measures].[Rate Difference] as [Measures].[End of Day Rate]-[Measures].[Average Rate], CAPTION='Rate Difference', DISPLAY_FOLDER='ISV_1/Finance', ASSOCIATED_MEASURE_GROUP='Exchange Rates'"));
            members.Add(0x0004, new MDXCommands("Adventure Works DW", "Adventure Works", "alter cube [Adventure Works]create member [Measures].[Reseller Discount per Order] as [Measures].[Discount Amount]/[Measures].[Reseller Order Count], CAPTION='Discount per Order', DISPLAY_FOLDER='ISV_1/Marketing', ASSOCIATED_MEASURE_GROUP='Reseller Orders'"));

            //Adding retrieved sets to 'sets' dictionary
            sets.Add(0xFFFF, new MDXCommands("Adventure Works DW", "Adventure Works", "create set [Adventure Works].[ISV_1 - Western Coast] as {[Geography].[Geography].[State-Province].&[VIC]&[AU], [Geography].[Geography].[State-Province].&[VIC]&[AU], [Geography].[Geography].[State-Province].&[CA]&[US], [Geography].[Geography].[State-Province].&[OR]&[US], [Geography].[Geography].[State-Province].&[WA]&[US]}, CAPTION='ISV_1 - Western Coast', DISPLAY_FOLDER='ISV_1/Common'"));
            sets.Add(0x5000, new MDXCommands("Adventure Works DW", "Adventure Works", "create DYNAMIC set [Adventure Works].[Touring Bikes] as {[Product].[Model Name].&[Touring-1000], [Product].[Model Name].&[Touring-2000], [Product].[Model Name].&[Touring-3000]}, CAPTION='Touring Bikes', DISPLAY_FOLDER='ISV_1/Operations'"));
            sets.Add(0x00A0, new MDXCommands("Adventure Works DW", "Adventure Works", "create DYNAMIC set [Adventure Works].[Mountain Bikes] as {[Product].[Model Name].&[Mountain-100], [Product].[Model Name].&[Mountain-200], [Product].[Model Name].&[Mountain-300], [Product].[Model Name].&[Mountain-400-W], [Product].[Model Name].&[Mountain-500]}, CAPTION='Mountain Bikes', DISPLAY_FOLDER='ISV_1/Finance'"));
            sets.Add(0x00C8, new MDXCommands("Adventure Works DW", "Adventure Works", "create DYNAMIC set [Adventure Works].[Road Bikes] as {[Product].[Model Name].&[Road-150], [Product].[Model Name].&[Road-250], [Product].[Model Name].&[Road-350-W], [Product].[Model Name].&[Road-450], [Product].[Model Name].&[Road-550-W], [Product].[Model Name].&[Road-650], [Product].[Model Name].&[Road-750]}, CAPTION='All Terrain Bikes', DISPLAY_FOLDER='ISV_1/Marketing'"));

            //Adding retrieved kpis to 'kpis' dictionary
            kpis.Add(0x0500, new MDXCommands("Adventure Works DW", "Adventure Works", "CREATE KPI [Adventure Works].[ISV_1 - Product Gross Profit Margin] AS [Measures].[Gross Profit Margin], GOAL = Case When [Product].[Category].CurrentMember Is [Product].[Category].[Accessories] Then .40 When [Product].[Category].CurrentMember Is [Product].[Category].[Bikes] Then .12 When [Product].[Category].CurrentMember Is [Product].[Category].[Clothing] Then .20 When [Product].[Category].CurrentMember Is [Product].[Category].[Components] Then .10 Else .12 End , STATUS = Case When KpiValue( 'Product Gross Profit Margin' ) / KpiGoal ('Product Gross Profit Margin' ) >= .90 Then 1 When KpiValue( 'Product Gross Profit Margin' ) / KpiGoal ('Product Gross Profit Margin' ) < .90 And KpiValue( 'Product Gross Profit Margin' ) / KpiGoal ('Product Gross Profit Margin' ) >= .80 Then 0 Else -1 End , STATUS_GRAPHIC = 'Cylinder' , TREND = Case When IsEmpty (ParallelPeriod ([Date].[Fiscal].[Fiscal Year], 1, [Date].[Fiscal].CurrentMember)) Then 0 When VBA!Abs (( KpiValue( 'Product Gross Profit Margin' ) - (KpiValue( 'Product Gross Profit Margin' ), ParallelPeriod ([Date].[Fiscal].[Fiscal Year], 1, [Date].[Fiscal].CurrentMember))) / (KpiValue( 'Product Gross Profit Margin' ), ParallelPeriod ([Date].[Fiscal].[Fiscal Year], 1, [Date].[Fiscal].CurrentMember))) <=.02 Then 0 When (KpiValue( 'Product Gross Profit Margin' ) - (KpiValue( 'Product Gross Profit Margin' ), ParallelPeriod ([Date].[Fiscal].[Fiscal Year], 1, [Date].[Fiscal].CurrentMember))) / (KpiValue( 'Product Gross Profit Margin' ), ParallelPeriod ([Date].[Fiscal].[Fiscal Year], 1, [Date].[Fiscal].CurrentMember)) >.02 Then 1 Else -1 End , TREND_GRAPHIC = 'Status arrow' , CAPTION = 'ISV_1 - Product Gross Profit Margin' , DISPLAY_FOLDER = 'ISV_1/Finance' , ASSOCIATED_MEASURE_GROUP = 'Sales Summary'"));

        }


        public static void DefineMembers(String databaseName, String cubeName, String usrName)
        {
            UInt32 userPermissions = 0;
            if (!users.ContainsKey(usrName))
            {
                return;
            }
            else
            {
                userPermissions = users[usrName];
            }
            foreach (UInt32 permissionKey in members.Keys)
            {
                if ((userPermissions & permissionKey)!= 0)
                {
                    MDXCommands currentCommand = members[permissionKey];

                    if ((currentCommand.databaseName == databaseName) && (currentCommand.cubeName == cubeName))
                    {
                        AdomdCommand cmd = new AdomdCommand();
                        cmd.CommandText = currentCommand.mdxCommand;
                        cmd.ExecuteNonQuery();
                        cmd.Dispose();
                    }
                }
            }

        }

        public static void DefineSets(String databaseName, String cubeName, String usrName)
        {
            UInt32 userPermissions = 0;
            if (!users.ContainsKey(usrName))
            {
                return;
            }
            else
            {
                userPermissions = users[usrName];
            }
            foreach (UInt32 permissionKey in sets.Keys)
            {
                if ((userPermissions & permissionKey) != 0)
                {
                    MDXCommands currentCommand = sets[permissionKey];

                    if ((currentCommand.databaseName == databaseName) && (currentCommand.cubeName == cubeName))
                    {
                        AdomdCommand cmd = new AdomdCommand();
                        cmd.CommandText = currentCommand.mdxCommand;
                        cmd.ExecuteNonQuery();
                        cmd.Dispose();
                    }
                }
            }
        }

        public static void DefineKPIs(String databaseName, String cubeName, String usrName)
        {
            UInt32 userPermissions = 0;
            if (!users.ContainsKey(usrName))
            {
                return;
            }
            else
            {
                userPermissions = users[usrName];
            }
            foreach (UInt32 permissionKey in kpis.Keys)
            {
                if ((userPermissions & permissionKey) != 0)
                {
                    MDXCommands currentCommand = kpis[permissionKey];

                    if ((currentCommand.databaseName == databaseName) && (currentCommand.cubeName == cubeName))
                    {
                        AdomdCommand cmd = new AdomdCommand();
                        cmd.CommandText = currentCommand.mdxCommand;
                        cmd.ExecuteNonQuery();
                        cmd.Dispose();
                    }
                }
            }
        }



    }
}
